package me.base.commom.service;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import me.base.commom.Serviceable;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * File Name             :  LocalCacheService
 * Author                :  sylar
 * Create Date           :  2018/4/18
 * Description           :  基于guava实现的本地缓存
 * Reviewed By           :
 * Reviewed On           :
 * Version History       :
 * Modified By           :
 * Modified Date         :
 * Comments              :
 * CopyRight             : COPYRIGHT(c) xxx.com   All Rights Reserved
 * *******************************************************************************************
 */
public class LocalCacheService<K, V> implements Serviceable {

    private final Cache<K, V> cache;

    /**
     * 构造本地缓存服务
     * 默认缓存数据条数： 1M
     * 读取后默认生存时间：1小时
     * 写入后默认生存时间：1小时
     */
    public LocalCacheService() {
        this(1024 * 1024, 1, 1, TimeUnit.HOURS);
    }

    /**
     * 构造本地缓存服务
     *
     * @param maximumSize   最大缓存条数
     * @param readDuration  读取后默认生存时间
     * @param writeDuration 写入后默认生存时间
     * @param timeUnit      时间单位
     */
    public LocalCacheService(long maximumSize, long readDuration, long writeDuration, TimeUnit timeUnit) {
        this(CacheBuilder
                .newBuilder()
                .maximumSize(maximumSize)
                .expireAfterWrite(writeDuration, timeUnit)
                .expireAfterAccess(readDuration, timeUnit)
                .build());
    }

    protected LocalCacheService(Cache<K, V> cache) {
        this.cache = cache;
    }

    @Override
    public void dispose() {
        cache.invalidateAll();
    }

    public V get(K k) {
        return cache.getIfPresent(k);
    }

    public void put(K key, V value) {
        if (value != cache.getIfPresent(key)) {
            cache.put(key, value);
        }
    }

    public void removeAll() {
        cache.invalidateAll();
    }

    public void remove(K key) {
        cache.invalidate(key);
    }

    public boolean containsKey(K key) {
        return cache.getIfPresent(key) != null;
    }

    public long size() {
        return cache.size();
    }

    public Map<K, V> getMap() {
        return cache.asMap();
    }
}
